package com.aau.edu;

import com.aau.edu.pojo.Author;
import com.aau.edu.pojo.Book;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamDemo04 {
    //常用终结操作
    public static void main(String[] args) {
        List<Author> authors = getAuthors();
        //forEach
        //对流中的元素进行遍历操作，我们通过传入的参数去指定对遍历到的元素进行什么具体的操作
        //例子：输出所有作家的名字
        authors.stream()
                .map(author -> author.getName())
                .distinct()
                .forEach(author -> System.out.println(author));
        System.out.println("--------------------------------");
        //count
        //可以用来获取当前流中元素的个数。
        //例子：打印这些作家的所出书籍的数目，注意删除重复元素。
        long count = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .count();
        System.out.println(count);

        System.out.println("---------------------------------");
        authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .forEach(author -> System.out.println(author));
        System.out.println("---------------------------------");
        //max&min
        //可以用来获取流中的最值。
        //例子：分别获取这些作家的所出书籍的最高分和最低分并打印
        //Stream<Author>->Stream<Book>->Stream<Integer>
        Optional<Integer> max = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .max((score1, score2) -> score1 - score2);

        Optional<Integer> min = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .min((score1, score2) -> score1 - score2);
        System.out.println(max.get());
        System.out.println(min.get());
        System.out.println("---------------------------------");
        //collect
        //把当前流转换成一个集合
        //需求：获取一个存放所有作者名字的list集合
        List<String> nameList = authors.stream()
                .map(author -> author.getName())
                .collect(Collectors.toList());
        System.out.println(nameList);
        System.out.println("---------------------------------");
        //需求：获取一个所有书名的set集合
        Set<String> bookNameSet = authors.stream()
                .flatMap(book -> book.getBooks().stream())
                .map(book -> book.getName())
                .collect(Collectors.toSet());
        System.out.println(bookNameSet);
        System.out.println("---------------------------------");
        //需求:获取一个Map集合，map的key为作者名，value为List
        //匿名内部类的写法
        Map<String, List<Book>> map1 = authors.stream()
                .distinct()
                .collect(Collectors.toMap(new Function<Author, String>() {
                    @Override
                    public String apply(Author author) {
                        return author.getName();
                    }
                }, new Function<Author, List<Book>>() {
                    @Override
                    public List<Book> apply(Author author) {
                        return author.getBooks();
                    }
                }));
        Map<String, List<Book>> map = authors.stream()
                .distinct()//去重去的是作者的重
                .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
        /*for (Map.Entry<String, List<Book>> stringListEntry : map.entrySet()) {
            System.out.println(stringListEntry.getKey() + ":" + stringListEntry.getValue());
            System.out.println("#################################");
        }*/
        System.out.println(map);
        System.out.println("---------------------------------");
        //将List集合对象里面的对象年龄相加，mapToInt(Author::getAge), 还可以用MapToDouble还可以用MapToLong
        int sum = authors.stream().mapToInt(Author::getAge).sum();
        System.out.println(sum);

    }

    private static List<Author> getAuthors() {
        //数据初始化
        Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
        Author author2 = new Author(2L, "亚拉索", 15, "狂风也追逐不上他的思考速度", null);
        Author author3 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);
        Author author4 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);

        //书籍列表
        List<Book> books1 = new ArrayList<>();
        List<Book> books2 = new ArrayList<>();
        List<Book> books3 = new ArrayList<>();

        books1.add(new Book(1L, "刀的两侧是光明与黑暗", "哲学,爱情", 88, "用一把刀划分了爱恨"));
        books1.add(new Book(2L, "一个人不能死在同一把刀下", "个人成长,爱情", 99, "讲述如何从失败中明悟真理"));

        books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
        books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
        books2.add(new Book(4L, "吹或不吹", "爱情,个人传记", 56, "一个哲学家的恋爱观注定很难把他所在的时代理解"));

        books3.add(new Book(5L, "你的剑就是我的剑", "爱情", 56, "无法想象一个武者能对他的伴侣这么的宽容"));
        books3.add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢？"));
        books3.add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢？"));

        author.setBooks(books1);
        author2.setBooks(books2);
        author3.setBooks(books3);
        author4.setBooks(books3);

        List<Author> authorsList = new ArrayList<>(Arrays.asList(author, author2, author3, author4));
        return authorsList;
    }
}
